package com.tqjc.business.interactivewithscan.core.operation;

import com.alibaba.fastjson.JSONObject;
import com.tqjc.business.interactivewithscan.core.thread.NormalThread;
import com.tqjc.business.interactivewithscan.entity.DeviceSocketClient;
import com.tqjc.business.interactivewithscan.entity.ScanDeviceData;
import com.tqjc.business.interactivewithscan.entity.UfcDeviceInfo;
import com.tqjc.business.interactivewithscan.exception.CustomException;
import com.tqjc.business.interactivewithscan.service.ScanDeviceDataService;
import com.tqjc.business.interactivewithscan.uils.EmptyUtil;
import org.mybatis.spring.MyBatisSystemException;

/**
 * @program: C20005_Xianggang_new
 * @description:
 * @author: Patienyon
 * @create: 2023-11-07 14:21
 **/
public abstract class SpecificOperation<T extends NormalThread> {
    protected JSONObject data;
    protected ScanDeviceData device;
    protected UfcDeviceInfo deviceInfo;
    protected DeviceSocketClient socketClient;
    protected T deviceThread;
    private String describe;
    private int logIndex = 0;

    public SpecificOperation<T> setThread(T t) {
        this.device = t.getDevice();
        this.deviceInfo = t.getDeviceInfo();
        this.socketClient = t.getSocketClient();
        this.data = t.getData();
        this.deviceThread = t;
        return this;
    }

    public SpecificOperation setDescribe(String describe) {
        this.describe = describe;
        return this;
    }

    public SpecificOperation setDevice(ScanDeviceData device, UfcDeviceInfo deviceInfo, DeviceSocketClient socketClient) {
        this.device = device;
        this.deviceInfo = deviceInfo;
        this.socketClient = socketClient;
        return this;
    }

    /**
     * 是否调度暂停任务
     *
     * @return 是否需要继续执行
     */
//    protected boolean suspend() {
//        UfcTiancheTask tiancheTask = data.getObject("tiancheTask", UfcTiancheTask.class);
//        //只有天车任务才有此校验
//        if (EmptyUtil.isEmpty(tiancheTask)) {
//            return false;
//        }
//        return tiancheTask.getSuspend();
//    }

    ;

    /**
     * 初始化
     *
     * @return 是否需要继续执行
     */
    protected abstract boolean init();

    /**
     * 使用socket发送命令
     *
     * @return 是否需要继续执行
     */
    protected abstract boolean operationCommon();


    /**
     * 结束
     *
     * @return 是否需要继续执行
     */
    protected abstract boolean destroy();

    /**
     * 该动作自己的逻辑处理
     */
    protected abstract void ownLogic();

    /**
     * 操作所有步骤
     *
     * @return 执行结果是否正确
     */
    public boolean operation(int i) {
        //初始步骤执行结构 true：需要执行，false：不需要执行
        boolean init = true;
        boolean suspend = true;
        boolean operation = true;
        boolean destroy = true;
        try {
            do {
                ownLogic();
                //设备是否需要重新连接(断开连接后并且重连失败，放弃后续任务)
                Boolean socketIsReconnect = data.getBoolean("socketIsReconnect");
                if (!EmptyUtil.isEmpty(socketIsReconnect) && socketIsReconnect) {
                    return true;
                }
                if (!socketClient.succeeded()) {
                    data.put("socketIsReconnect", true);
                    continue;
                }
                if (init) {
                    if (logIndex == 0) {
                        logIndex++;
                        System.err.println("【" + device.getDeviceName() + "】：" + "开始执行【" + describe + "】");
                    }
                    init = init();
                    //如果初始化失败则认定为之前操作执行结果不正确
                    if (init) {
                        if (i == 0){
                            continue;
                        }
                        return false;
                    }
                }
//                if (suspend) {
//                    suspend = suspend();
//                    if (suspend) {
//                        continue;
//                    }
//                }
                if (operation) {
                    operation = operationCommon();
                    //若 operation 需要再次执行，意味着初始化不完善，需要重新初始化
                    suspend = operation;
                    init = operation;
                    continue;
                }
                if (destroy) {
                    destroy = destroy();
                    //若 destroy 需要再次执行，意味着operation不完善，需要执行
                    operation = destroy;
                    continue;
                }
                logIndex = 0;
                System.err.println("【" + device.getDeviceName() + "】：" + "执行完成【" + describe + "】");
                break;
            } while (true);
        } catch (CustomException e) {
            System.err.println(e.getMsg());
            e.printStackTrace();
            if (e.getCode() == 109009) {
                return true;
            }
            throw new CustomException(-1, "【" + device.getDeviceName() + "】执行【" + describe + "】失败！");
        } catch (MyBatisSystemException e) {
            return false;
        } catch (Exception e) {
            e.getMessage();
            e.printStackTrace();
            throw new CustomException(-1, "【" + device.getDeviceName() + "】执行【" + describe + "】失败！");
        }
        return true;
    }

}
